package com.atguigu.gmall.realtime.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.atguigu.gmall.realtime.common.GmallConfig;
import org.apache.commons.lang3.StringUtils;
import org.apache.hadoop.hbase.client.Connection;
import redis.clients.jedis.Jedis;

/**
 * @author Felix
 * @date 2023/8/10
 * 查询维度的工具类
 */
public class DimUtil {

    /**
     * 查询维度的方法
     * @param jedis         操作Redis的客户端
     * @param conn    Hbase的连接
     * @param nameSpace     表空间
     * @param tableName     表
     * @param rowKey        rowkey
     * @return
     * 优化：旁路缓存
     * 思路：先从缓存中获取维度数据，如果在缓存中找到了要关联的维度，直接将其作为方法的返回值进行返回(缓存命中)；
     *      如果在缓存中没有找到要关联的维度，发送请求到hbase中进行查询，并将查询出来的维度放到缓存缓存起来，
     *      方便下次查询使用
     * 缓存产品选型
     *      redis：性能不错，维护性好     √
     *      状态：性能很好，维护性差
     * Redis相关的设置
     *      key:    维度表名:主键
     *      value:  String
     *      expire: 1DAY   避免冷数据常驻内容，给内存带来压力
     *      注意：如果维度数据发生了变化，将缓存的内容清除掉
     */
    public static JSONObject getDimInfo(Jedis jedis,
                                        Connection conn,
                                        String nameSpace,
                                        String tableName,
                                        String rowKey){
        //拼接从Redis中查询维度数据的key
        String redisKey = tableName.toLowerCase() + ":" + rowKey;

        String dimStr = null;
        JSONObject dimJsonObj = null;

        //先从缓存中获取维度数据
        dimStr = jedis.get(redisKey);

        //判断从Redis中查询出来的维度数据是不是为空
        if(StringUtils.isNotEmpty(dimStr)){
            System.out.println("从Redis中获取维度数据");
            //如果在缓存中找到了要关联的维度，直接将其作为方法的返回值进行返回(缓存命中)
            dimJsonObj = JSON.parseObject(dimStr);
        }else{
            System.out.println("从hbase中查询维度数据");
            //如果在缓存中没有找到要关联的维度，发送请求到hbase中进行查询
            //底层还是调用HbaseUtil.getDimInfoFromHbase
            dimJsonObj = HbaseUtil.getDimInfoFromHbase(conn, nameSpace, tableName, rowKey);
            if(dimJsonObj != null){
                //将查询出来的维度放到缓存缓存起来
                jedis.setex(redisKey,3600*24,dimJsonObj.toJSONString());
            }else{
                System.out.println("你要查询的维度数据不存在");
            }
        }
        return dimJsonObj;
    }

    public static void main(String[] args) {
        Jedis jedis = RedisUtil.getRedisClient();
        Connection conn = HbaseUtil.getHbaseConnection();
        System.out.println(getDimInfo(jedis, conn, GmallConfig.HBASE_NAMESPACE, "dim_base_trademark", "1"));
    }
    //从Redis中清除缓存的数据
    public static void delCached(String tableName,String rowKey){
        String redisKey = tableName.toLowerCase() + ":" + rowKey;
        Jedis jedis = null;
        try {
            jedis = RedisUtil.getRedisClient();
            jedis.del(redisKey);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            RedisUtil.closeRedisClient(jedis);
        }
    }
}
